import React, { version } from 'react';
import { Provider } from 'mobx-react';
import { hideInstance } from '@discuzq/design/dist/components/image-previewer/layouts/web';
import App from 'next/app';
import getPlatform from '@common/utils/get-platform';
import initializeStore from '@common/store';
import PayBoxProvider from '../components/payBox/payBoxProvider';
import isServer from '@common/utils/is-server';
import csrRouterRedirect from '@common/utils/csr-router-redirect';
import Router from '@discuzq/sdk/dist/router';
import { default as NextRouter } from "next/router";
// import sentry from '@common/utils/sentry';
import '../styles/index.scss';
import CustomHead from '@components/custom-head';
import Head from 'next/head';
import monitor from '@common/utils/monitor';
import { detectH5Orient } from '@common/utils/detect-orient';
import browser from '@common/utils/browser';
import Toast from '@discuzq/design/dist/components/toast';
import { STORAGE_KEY, STORAGE_TYPE } from '@common/utils/viewcount-in-storage';

const API_VERSION = 2;
import DZQPluginCenter from '@discuzq/plugin-center';
import PluginDevelopTools from '../utils/PluginDevelopTools';
import { throttle } from '@common/utils/throttle-debounce.js';

// if (!isServer()) {
//   process.env.NODE_ENV === 'production' && sentry();
// }
const appStore = initializeStore();
DZQPluginCenter.initStore(appStore.plugin.setPluginComponent.bind(appStore.plugin));

function parseURL(url) {
  var a = document.createElement('a');
  a.href = url;
  return {
      source: a.href,
      protocol: a.protocol.replace(':',''),
      host: a.hostname,
      port: a.port,
      query: a.search,
      params: (function(){
          var ret = {},
          seg = a.search.replace(/^\?/,'').split('&'),
          len = seg.length, i = 0, s;
          for (;i<len;i++) {
              if (!seg[i]) { continue; }
              s = seg[i].split('=');
              ret[s[0]] = s[1];
          }
          return ret;
      })(),
      file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],
      hash: a.hash.replace('#',''),
      path: a.pathname.replace(/^([^\/])/,'/$1'),
      relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1],
      segments: a.pathname.replace(/^\//,'').split('/')
  };
}

class DzqApp extends App {
  constructor(props) {
    super(props);
    this.appStore = appStore;
    this.updateSize = throttle(this.updateSize.bind(this), 100);
    this.toastInstance = null;

    this.isFirstLoad = false;
    this.routerEventEmitted = 0;
  }

  // 路由跳转时，需要清理图片预览器
  cleanImgViewer = () => {
    try {
      if (hideInstance) {
        hideInstance();
      }
    } catch (e) {
      console.error(e);
    }
  };

  listenRouterChangeAndClean() {
    // FIXME: 此种写法不好
    if (!isServer()) {
      window.addEventListener('popstate', this.cleanImgViewer, false);
    }
  }

  checkAppUpdate(currentVersion) {
    function compareVersion(v1, v2) {
      let v1List = v1.split('.');
      let v2List = v2.split('.');
      let needUpdate = false;
      if (v1List.length != v2List.length) return true;

      let v1Num, v2Num;
      for (let i = v1List.length - 1; i >= 0; i--) {
        v1Num = parseInt(v1List[i]);
        v2Num = parseInt(v2List[i]);
        if (v1Num < v2Num) {
          needUpdate = true;
        } else if (v1Num > v2Num) {
          needUpdate = false;
        }
      }
      return needUpdate;
    }

    var headers = new Headers();
    headers.append('pragma', 'no-cache');
    headers.append('cache-control', 'no-cache');
    fetch('/app/version.json', {
      method: 'GET',
      headers,
      cache: 'no-store',
    }).then(res => {
      if (res.ok) {
        return res.json();
      }
      return false;
    }).then(updateInfo => {
      if (!updateInfo || !('version' in updateInfo)) return;

      if (compareVersion(currentVersion, updateInfo.version)) {
        //需要更新
        console.log("APP有更新", updateInfo);
        if (localStorage.getItem('skipped_app_version') == updateInfo.version) {
          console.log("已跳过此版本");
          return;
        }

        navigator.notification.confirm(
          updateInfo.description,
          (btn) => {
            switch (btn) {
              case 2:
                localStorage.setItem('skipped_app_version', updateInfo.version);
                break;
              case 3:
                if (API_VERSION >= updateInfo.api_version) {
                  //在APP内打开页面
                  Router.push({ url: '/thread/' + updateInfo.thread_id });
                } else {
                  //在浏览器中打开页面
                  navigator.app.loadUrl(updateInfo.url, {openExternal : true});
                }
                break;
            }
          },
          '软件更新',
          ['取消', '跳过此版本', '前往更新']
        );
      }
    }).catch(err => {
      console.error("无法检查更新", err);
    });
  }

  delegateBackButton() {
    let lastBackButtonFired = 0;
    document.addEventListener("backbutton", event => {
      if (location.pathname === '/') {
        event.preventDefault();
        let delay = 2000;
        let time = new Date().getTime();
        if (time - lastBackButtonFired > delay) {
          plugins.toast.showWithOptions({
            message: "再次点击返回键退出",
            duration: "short",
            position: "center",
          });
          lastBackButtonFired = time;
        } else {
          navigator.app.exitApp();
        }
      } else {
        history.back();
      }
    });
  }

  cordovaLoaded() {
    cordova.getAppVersion.getVersionNumber().then((version) => {
      this.checkAppUpdate(version);
    });
    this.delegateBackButton();

    // 隐藏Splash
    if (window.IsekaiFakeSplash) {
      IsekaiFakeSplash.hide();
    }

    if (window.JPush) {
      JPush.init();
    }

    if (window.IsekaiPageTransition) {
      let inAnimate = false;
      let longLoading = false;

      let startRouterAnimation = () => {
        if(!inAnimate) {
          if (!window.animateIsBackward) {
            inAnimate = true;
            IsekaiPageTransition.animateForward().then(() => {
              inAnimate = false;
            });
          } else {
            inAnimate = true;
            IsekaiPageTransition.animateBackward().then(() => {
              inAnimate = false;
            });
          }
        }
      }
      
      let handleRouteChange = (url) => {
        console.log('router start', url, this.routerEventEmitted);
        if (!this.isFirstLoad) {
          if (this.routerEventEmitted <= 0) {
            IsekaiPageTransition.freeze();
          } else if (!longLoading) { // 多次触发事件，显示加载提示
            longLoading = true;
            navigator.notification.activityStart('加载中', '请稍等');
          }
          this.routerEventEmitted ++;
        }
      }

      let handleRouteChangeComplete = (url) => {
        console.log('router end', url, this.routerEventEmitted);
        if (this.isFirstLoad) { // 屏蔽初次加载
          this.isFirstLoad = false;
        } else if (this.routerEventEmitted > 1) { // 首页的路由事件会触发两次，忽略第一次
          this.routerEventEmitted --;
        } else {
          if (longLoading) {
            setTimeout(() => {
              navigator.notification.activityStop();
              longLoading = false;
            }, 500);
            setTimeout(() => {
              startRouterAnimation();
              window.animateIsBackward = false;
            }, 600);
          } else {
            startRouterAnimation();
            window.animateIsBackward = false;
          }
          this.routerEventEmitted = 0;
        }
      };

      NextRouter.events.on('routeChangeStart', handleRouteChange);
      NextRouter.events.on('routeChangeComplete', handleRouteChangeComplete);
    }

    if (window.IsekaiSavePicture) {
      function savePicture(url) {
        let promise;
        if (url.indexOf('data:image/png;base64,') === 0) {
          promise = plugins.savePicture.fromBase64(url.substr(22), 'image/png');
        } else {
          promise = plugins.savePicture.fromUrl(url);
        }
        promise.then(() => {
          plugins.toast.showWithOptions({
            message: "图片已保存",
            duration: "short",
            position: "center"
          });
        }).catch((errCode) => {
          var errMsg = '未知错误';
          switch (errCode) {
            case 'PERMISSION_DENIED':
              errMsg = '没有访问存储空间的权限';
              break;
            case 'NETWORK_ERROR':
              errMsg = '网络错误';
              break;
            case 'FILE_IO_ERROR':
              errMsg = '无法写入文件';
              break;
          }
          console.error('IsekaiSavePicture', errCode);
          plugins.toast.showWithOptions({
            message: "图片保存错误: " + errMsg,
            duration: "long",
            position: "center"
          });
        });
      }

      function imageContextMenu(url, element) {
        var options = {
          'title': '操作',
          'buttonLabels': ['保存图片'],
          'addCancelButtonWithLabel': '取消',
          'androidTheme': plugins.actionsheet.ANDROID_THEMES.THEME_DEVICE_DEFAULT_LIGHT,
          'androidEnableCancelButton': true,
          'winphoneEnableCancelButton': true
        };
        plugins.actionsheet.show(options, (selected) => {
          switch (selected) {
            case 1:
              savePicture(url);
              break;
          }
        });
      }

      document.addEventListener('contextmenu', (e) => {
        if (e.target instanceof HTMLImageElement) {
          imageContextMenu(e.target.src);
        }
      });
    }
  }

  pageComponentDidMount() {
    console.log('pageComponentDidMount');
  }

  componentDidMount() {
    console.log(process.env.DISCUZ_BUILDINFO);
    if (window.performance) {
      monitor.call('reportTime', {
        eventName: 'fist-render',
        duration: Date.now() - performance.timing.navigationStart,
      });
    }

    this.initOretation();
    window.addEventListener('resize', this.updateSize);
    csrRouterRedirect();
    this.listenRouterChangeAndClean();

    if (!isServer()) {
      window.addEventListener("beforeunload", () => {
        if (STORAGE_TYPE === "session") sessionStorage.removeItem(STORAGE_KEY);
      });

      if ('_cordovaNative' in window) {
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = '/cordova.js';
        document.head.append(script);
        document.addEventListener('deviceready', () => {
          this.cordovaLoaded();
        }, false);
        
        function onRouterFirstLoaded() {
          this.isFirstLoad = false;
          NextRouter.events.off('routeChangeComplete', onRouterFirstLoaded);
        }
        NextRouter.events.on('routeChangeComplete', onRouterFirstLoaded.bind(this));

        // 处理scheme
        document.addEventListener("scheme.openUrl", function (event) {
          console.log('opened by scheme', event);
          if (!event.url) return true;
          var url = parseURL(event.url);
          var path = url.path.replace(/^(\/)+/g, '/');
          var nid = url.params ? url.params.nid : null;

          if (path) {
            Router.push({ url: path });
          }

          if (nid) {
              MobileApp.setNotificationReaded(nid);
          }
        });
      }
    }

    //  // 测试
    // setTimeout(() => {
    //   let js = false;
    //   let css = false;
      // const script = document.createElement('script');
      // script.src = "http://0.0.0.0:8081/dist/CustomIfram/index.js";
      // script.onload = () => {
      //   console.log('加载完毕！');
      //   js = true;
      //   // if (css) {
      //     const {map, pluginName} = DZQPluginCenter.register(window.DZQPlugin['CustomIfram'].default);
      //     console.log()
      //     this.appStore.plugin.setPluginComponent(pluginName, map);

      //   // }
    //   }

    //   const script2 = document.createElement('script');
    //   script2.src = "http://0.0.0.0:8081/dist/CustomIframDisplay/index.js";
    //   script2.onload = () => {
    //     console.log('加载完毕！');
    //     js = true;
    //     // if (css) {
    //       const {map, pluginName} = DZQPluginCenter.register(window.DZQPlugin['CustomIframDisplay'].default);
    //       console.log()
    //       this.appStore.plugin.setPluginComponent(pluginName, map);

    //     // }
    //   }

    //   const script3 = document.createElement('script');
    //   script3.src = "http://0.0.0.0:8081/dist/CustomIframPost/index.js";
    //   script3.onload = () => {
    //     console.log('加载完毕！');
    //     js = true;
    //     // if (css) {
    //       const {map, pluginName} = DZQPluginCenter.register(window.DZQPlugin['CustomIframPost'].default);
    //       console.log()
    //       this.appStore.plugin.setPluginComponent(pluginName, map);

    //     // }
    //   }

    //   // document.body.appendChild(link);
    //   document.body.appendChild(script);
    //   document.body.appendChild(script2);
    //   document.body.appendChild(script3);
    // }, 3000);
  }

  componentWillUnmount() {
    if (!isServer()) {
      window.removeEventListener('resize', this.updateSize);
      window.removeEventListener('popstate', this.cleanImgViewer);
      window.removeEventListener("beforeunload", () => {
        if (STORAGE_TYPE === "session") sessionStorage.removeItem(STORAGE_KEY);
      });
    }
  }

  // 出错捕获
  componentDidCatch(error, info) {
    console.error(error);
    console.error(info);
    // Router.replace({ url: '/render-error' });
  }

  // 移动端检测横屏
  initOretation() {
    this.toastInstance?.destroy();

    if (browser.env('mobile') && !browser.env('iPad')) {
      const isVertical = detectH5Orient();
      if (!isVertical) {
        this.toastInstance = Toast.info({
          content: '为了更好的体验，请使用竖屏浏览',
          duration: 5000,
        });
      }
    }
  }

  updateSize() {
    const oldPlatform = this.appStore.site.platform;
    const newPlatform = getPlatform(window.navigator.userAgent);
    this.appStore.site.setPlatform(newPlatform);
    this.initOretation();

    if (oldPlatform !== newPlatform) {
      console.log('重新注册插件');
      DZQPluginCenter.refreshRegister();
    }
  }

  render() {
    const { Component, pageProps } = this.props;
    return (
      <div className={`dzq-theme--${this.appStore.site.theme}`}>
        <Provider {...this.appStore}>
          <Head>
            <meta
              key="viewport"
              name="viewport"
              content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover"
            />
          </Head>
          <CustomHead />
         <PluginDevelopTools/>
          <PayBoxProvider>
            <Component componentDidMount={this.pageComponentDidMount} {...pageProps} />
          </PayBoxProvider>
        </Provider>
      </div>
    );
  }
}

export default DzqApp;
